package cn.hr.service.impl;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import cn.hr.dao.mapper.ArchivesMapper;
import cn.hr.dao.mapper.MissionTypeMapper;
import cn.hr.dao.mapper.PayrollCrewMapper;
import cn.hr.dao.mapper.PayrollDetailMapper;
import cn.hr.dao.mapper.PostMapper;
import cn.hr.dao.mapper.SalProStanMapper;
import cn.hr.dao.mapper.SalaryStandardMapper;
import cn.hr.pojo.MissionType;
import cn.hr.pojo.PayrollCrew;
import cn.hr.pojo.PayrollDetail;
import cn.hr.pojo.SalaryStandard;
import cn.hr.utils.Constants;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.annotations.Param;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import cn.hr.dao.mapper.PayrollOMapper;
import cn.hr.pojo.PayrollO;
import cn.hr.service.PayrollOService;

/**
 * 组织工资单服务接口实现类
 *
 * @author MO
 */
@CacheConfig(cacheNames = "payrollO")
@Scope("prototype")
@Service("payrollOService")
public class PayrollOServiceImpl implements PayrollOService {
    @Resource
    private PayrollOMapper payrollOMapper;
    @Resource
    private ArchivesMapper archivesMapper;
    @Resource
    private SalaryStandardMapper salaryStandardMapper;
    @Resource
    private PayrollCrewMapper payrollCrewMapper;
    @Resource
    private PayrollDetailMapper payrollDetailMapper;
    @Resource
    private SalProStanMapper salProStanMapper;
    @Resource
    private MissionTypeMapper missionTypeMapper;

    @Override
    public boolean insert(PayrollO t) throws Exception {
        if (payrollOMapper.findMaxId() == null) {
            t.setCode(Constants.PAYROLLO_CODE + (1));
        } else {
            t.setCode(Constants.PAYROLLO_CODE + (payrollOMapper.findMaxId() + 1));
        }
        t.setCounto(archivesMapper.findCountByOId(t.getoId()));//设置部门总人数
        if (t.getCounto() > 0) {
            List<Map> sals = archivesMapper.findSalSByOId(t.getoId());//根据部门id分组查询所有人事档案薪酬标准id及数量
            BigDecimal money = new BigDecimal(0);
            for (Map map : sals) {//计算薪酬标准金额
                money = money.add(salaryStandardMapper.get((Integer) map.get("salS")).getTotalMoney()).multiply(new BigDecimal(String.valueOf(map.get("salNum"))));
            }
            t.setTotalMoney(money);
        } else {
            t.setTotalMoney(BigDecimal.valueOf(0));
        }
        t.setCreatedDate(new Date());
        t.setAuditStatus(8);
        if (payrollOMapper.insert(t) <= 0) {
            return false;
        } else {
            List<Map> archivesMap = archivesMapper.findArchivesByOId(t.getoId());//根据部门id查询所有职员
            for (Map map : archivesMap) {//循环添加PayrollCrew
                PayrollCrew crew = new PayrollCrew();
                crew.setaId((Integer) map.get("id"));
                crew.setPoId(t.getId());
                crew.setDockPay(new BigDecimal(0));
                SalaryStandard salaryStandard = salaryStandardMapper.get((Integer) map.get("salS"));
                crew.setTotalMoney(salaryStandard.getTotalMoney());
                crew.setCreatedById(t.getCreatedById());
                crew.setCreatedDate(new Date());
                if (payrollCrewMapper.insert(crew) <= 0) {
                    return false;
                } else {
                    List<Map> salProStanMap = salProStanMapper.findListByCondition(map);
                    for (Map salProStan : salProStanMap) {//循环添加PayrollDetail
                        PayrollDetail payrollDetail = new PayrollDetail();
                        payrollDetail.setCrewId(crew.getId());
                        payrollDetail.setSalP((Integer) salProStan.get("salP"));
                        payrollDetail.setProMoney((BigDecimal) salProStan.get("proMoney"));
                        payrollDetail.setCreatedById(t.getCreatedById());
                        payrollDetail.setCreatedDate(new Date());
                        if (payrollDetailMapper.insert(payrollDetail) <= 0) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    @CacheEvict(value = {"payrollO", "payrollCrew", "payrollDetail", "mission"}, allEntries = true)
    public boolean update(PayrollO t) throws Exception {
        for (PayrollCrew payrollCrew : t.getCrewList()) {
            for (PayrollDetail payrollDetail : payrollCrew.getDetailList()) {
                payrollDetail.setModifyDate(new Date());
                if (payrollDetailMapper.update(payrollDetail) != 1) {
                    return false;
                }
            }
            payrollCrew.setModifyDate(new Date());
            if (payrollCrewMapper.update(payrollCrew) != 1) {
                return false;
            }
        }
        t.setModifyDate(new Date());
        if (payrollOMapper.update(t) != 1) {
            return false;
        }
        if (t.getAuditStatus() == 12) {
            MissionType missionType = new MissionType();
            missionType.setCreatedById(t.getModifyById());
            missionType.setCreatedDate(new Date());
            missionType.setName(t.getCode() + "薪酬发放审核");
            missionType.setTypeId(39);
            missionType.setTableId(t.getId());
            if (missionTypeMapper.insert(missionType) != 1) {
                return false;
            }
        } else if (t.getAuditStatus() == 11) {
            if (missionTypeMapper.deleteByTableIdAndTypeId(39, t.getId()) <= 0) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean delete(Integer id) throws Exception {
        Map map = new HashMap();
        map.put("poId", id);
        List<Map> payrollCrewMap = payrollCrewMapper.findListByCondition(map);
        for (Map crew : payrollCrewMap) {
            map.put("crewId", crew.get("id"));
            List<Map> detailMap = payrollDetailMapper.findListByCondition(map);
            for (Map detail : detailMap) {
                if (payrollDetailMapper.delete((Integer) detail.get("id")) != 1) {
                    return false;
                }
            }
            if (payrollCrewMapper.delete((Integer) crew.get("id")) != 1) {
                return false;
            }
        }
        return payrollOMapper.delete(id) == 1;
    }

    @Override
    public PayrollO get(Integer id) throws Exception {
        return payrollOMapper.get(id);
    }

    @Override
    public PageInfo<Map> findListByCondition(Map m, int pageNo) throws Exception {
        PageHelper.startPage(pageNo, Constants.PAGESIZE);
        List<Map> list = payrollOMapper.findListByCondition(m);
        return new PageInfo<Map>(list);
    }

    @Override
    public Long findCountByCondition(Map m) throws Exception {
        return payrollOMapper.findCountByCondition(m);
    }

    @Override
    public Map findMapById(String id) throws Exception {
        return payrollOMapper.findMapById(id);
    }
}
